Skip to content

feat: add SSE stream endpoint with GitHub webhook and polling fallback (#237)#299

Closed
devendra-w wants to merge 4 commits into
Priyanshu-byte-coder:mainfrom
devendra-w:feat/sse-stream
Closed

feat: add SSE stream endpoint with GitHub webhook and polling fallback (#237)#299
devendra-w wants to merge 4 commits into
Priyanshu-byte-coder:mainfrom
devendra-w:feat/sse-stream

Conversation

@devendra-w
Copy link
Copy Markdown
Contributor

Summary

Dashboard metrics are currently fetched once on load and go stale for active users. This PR adds a Server-Sent Events (SSE) endpoint so the server can push real-time updates when new commits are detected via GitHub webhooks. Falls back to 60s polling if SSE fails.
Closes #237

Type of Change

  • New feature

Changes Made

  • Added src/lib/sse.ts — shared in-memory Map to store active SSE connections per user
  • Added src/app/api/stream/route.ts — SSE endpoint at GET /api/stream?userId=
  • Added src/app/api/webhooks/github/route.ts — GitHub webhook receiver at POST /api/webhooks/github with HMAC-SHA256 signature verification using crypto.timingSafeEqual
  • Added src/components/SSEListener.tsx — client component that subscribes to SSE and refreshes dashboard on events, with 60s polling fallback if SSE fails
  • Updated src/app/dashboard/page.tsx — added SSEListener component
  • Updated .env.example — added GITHUB_WEBHOOK_SECRET

How to Test

  1. Run npm run dev
  2. Open browser devtools → Network tab → filter by stream
  3. Navigate to /dashboard — you should see an active stream SSE connection
  4. To test webhook: use a tool like ngrok to expose localhost, register the webhook URL on GitHub, and push a commit

Screenshots (if UI change)

N/A - Infrastructure change

Checklist

  • Linked issue in summary
  • npm run lint passes locally
  • Self-reviewed the diff
  • Added/updated tests if applicable

@vercel
Copy link
Copy Markdown

vercel Bot commented May 17, 2026

@devendra-w is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

This PR conflicts with recently merged changes. Please rebase onto main:

git fetch upstream && git rebase upstream/main

Resolve any conflicts, push, and I'll review.

@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

Hi @devendra-w — this PR has a merge conflict with main. Please rebase your branch:

git fetch upstream
git rebase upstream/main
# resolve conflicts, then:
git push --force-with-lease

Once rebased, we'll review and merge.

@devendra-w
Copy link
Copy Markdown
Contributor Author

Rebased on main and resolved the merge conflict. Ready for merge @Priyanshu-byte-coder !

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good concept, but several blocking issues:

1. In-memory SSE map doesn't work in serverless
sseConnections is a module-level Map in lib/sse.ts. Vercel deploys Next.js as serverless functions — each request may hit a different cold instance with its own empty map. When a webhook arrives, it writes to its instance's map; the SSE stream is open on a different instance's map. Events never reach the client. This requires a shared pub/sub layer (e.g., Redis pub/sub, or Vercel KV).

2. Missing auth on the SSE endpoint
GET /api/stream?userId=... has no session check. Anyone can subscribe to any user's SSE stream if they know the userId. Add getServerSession and verify the session's githubId matches the requested userId.

3. Duplicate code in stream/route.ts
The entire GET handler is pasted twice in the file. The second copy must be removed.

4. Removes CIAnalytics and Settings link from dashboard
dashboard/page.tsx removes <CIAnalytics /> and the Settings link. These are unrelated to SSE — revert those changes and keep only the <SSEListener> addition.

5. Wrong session field for userId
session?.user?.email ?? session?.user?.name ?? "" — the project uses session.githubId (not user.name). Use session?.githubId ?? "".

The webhook handling concept and SSE fallback-to-polling pattern are solid. Fix these and it's a useful feature.

@Priyanshu-byte-coder Priyanshu-byte-coder added level:advanced GSSoC: Advanced difficulty (55 pts) gssoc26 GSSoC 2026 contribution type:feature GSSoC type bonus: new feature labels May 20, 2026
Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issues found in this PR:

  • Missing EOF newline — add a trailing newline to all modified files.

@devendra-w
Copy link
Copy Markdown
Contributor Author

Hey @Priyanshu-byte-coder all changes made as requested ready for re-review and merge!
Thankyou!

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR is conflicting with main. Please rebase:

git fetch upstream
git rebase upstream/main
git push --force-with-lease

@devendra-w
Copy link
Copy Markdown
Contributor Author

Hi @Priyanshu-byte-coder , the TypeScript errors in src/app/api/metrics/contributions/route.ts and src/app/api/metrics/issues/route.ts are pre-existing issues on the main branch confirmed by git diff upstream/main showing zero changes to these files in this PR. These errors exist on main independently of my changes.

@devendra-w
Copy link
Copy Markdown
Contributor Author

Hey @Priyanshu-byte-coder, Addressed all review comments added auth to SSE endpoint, fixed userId to use session.githubId, removed duplicate handler, kept CIAnalytics intact. Pre-existing TypeScript errors in contributions/route.ts are base branch issues unrelated to this PR. Ready to merge!

@Priyanshu-byte-coder Priyanshu-byte-coder added the gssoc:approved GSSoC: PR approved for scoring label May 24, 2026
@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

This PR has merge conflicts with main. Please rebase on the latest main branch and re-request review. The approach is approved — just needs conflict resolution.

@devendra-w
Copy link
Copy Markdown
Contributor Author

Hi @Priyanshu-byte-coder! The merge conflicts have been resolved in a clean rebase. I've opened a new PR #998 that is cleanly based on the latest main with no merge commits. Closing this one in favor of the new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved GSSoC: PR approved for scoring gssoc26 GSSoC 2026 contribution level:advanced GSSoC: Advanced difficulty (55 pts) type:feature GSSoC type bonus: new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add server-sent events (SSE) endpoint for real-time dashboard refresh

2 participants